package com.jnks.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.jnks.config.mongoDB.MongoDbClient;
import com.jnks.constant.BaseServiceConstant;
import com.jnks.constant.DroneConstants;
import com.jnks.exception.BizException;
import com.jnks.pojo.domain.dto.DroneCoor;
import com.jnks.pojo.domain.dto.DroneRedis;
import com.jnks.pojo.domain.dto.DroneTarget;
import com.jnks.pojo.domain.vo.DroneCoorResponse;
import com.jnks.pojo.domain.vo.DroneCoorResponseVo;
import com.jnks.pojo.domain.vo.DroneDataReq;
import com.jnks.pojo.domain.vo.DroneRedisWzMqttVo;
import com.jnks.utils.GZipCompressUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;


/**
 * @author Ryo
 * @ClassName DroneDataServiceImpl.java
 * @createTime
 */
@Service
@Slf4j
public class DroneDataServiceImpl {
    private static ExecutorService executorService = new ThreadPoolExecutor(20, 20, 1000, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());

    @Autowired
    private MongoDbClient mongoDBClient;

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    /**
     * @description: 日常监测-获取在飞无人机列表  改
     * @author: Ryo
     * @date: 2024/4/9
     */
    public List<DroneRedisWzMqttVo> hisDroneDirectDaily() {
        List<DroneRedisWzMqttVo> outList = new ArrayList<>();
        Set<String> redis_drone_uni_key = redisTemplate.keys(DroneConstants.REDIS_DRONE_UNI_KEY.concat("*"));
        if (!redis_drone_uni_key.isEmpty()) {
            List<String> list = new ArrayList<String>(redis_drone_uni_key);
            List<List<String>> partitionList = Lists.partition(list, BaseServiceConstant.GROUP_SIZE);
            List<CompletableFuture<List<DroneRedisWzMqttVo>>> asyncList = new ArrayList<>();
            CompletableFuture<List<DroneRedisWzMqttVo>> listCompletableFuture;
            for (List<String> strings : partitionList) {
                //获取分割后的每一个集合，走异步处理
                listCompletableFuture =
                        CompletableFuture.supplyAsync(() -> this.getDroneRedis(strings), executorService);
                asyncList.add(listCompletableFuture);
            }
            CompletableFuture<Void> allFuture = CompletableFuture.allOf(asyncList.toArray(new CompletableFuture[0]));
            List<List<DroneRedisWzMqttVo>> future = allFuture.thenApply(t -> asyncList.stream().map(CompletableFuture::join).collect(Collectors.toList())).join();
            future.forEach(outList::addAll);
            outList.sort(Comparator.comparing(DroneRedisWzMqttVo::getTakeoffTime).reversed());
            return outList;
        }
        return outList;
    }

    public DroneCoorResponseVo hisDroneCoors(String droneKey) {
        DroneCoorResponseVo droneCoorResponseVo = new DroneCoorResponseVo();
        if (redisTemplate.hasKey(droneKey)) {
            String sys = (String) redisTemplate.opsForValue().get(droneKey);

            System.out.println("sys==========================="+sys);
            String uncompress = GZipCompressUtil.uncompress(sys);
            System.out.println("uncompress==========================="+uncompress);
            DroneRedis droneRedis = JSONObject.parseObject(uncompress, DroneRedis.class);

            if (droneRedis.getType() == 3 && droneRedis.getCoorKeyList() != null) {
                List<DroneCoor> droneCoors = new ArrayList<>();
                for (String s : droneRedis.getCoorKeyList()) {
                    List<DroneCoor> droneCoorEidList = (List<DroneCoor>) redisTemplate.opsForValue().get(s);
                    droneCoors.addAll(droneCoorEidList);
                }
                droneCoors.addAll(droneRedis.getCoors());
            }else{
                droneCoorResponseVo.setCoors(droneRedis.getCoors());
            }
            return droneCoorResponseVo;
        } else {
            throw new BizException("405", "该无人机已降落");
        }
    }

    /**
     * @ClassName DroneDataServiceImpl
     * @Desc  根据条件和集合名称查询数据
     * @Date
     * @Version 1.0
     */
    public DroneCoorResponse getDroneData(DroneDataReq req) throws ParseException {
        DroneCoorResponse droneCoorResponse = new DroneCoorResponse();
        // 封装查询条件
        Query query = new Query();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = sdf.parse(req.getTakeOffTime());
        // 注：MongoDB 对于数据类型很敏感，如 age 这样的字段存入时类型为 int，却在设置条件是写为 is("2")，这样是查询不到结果的
        query.addCriteria(new Criteria().and("intrusionStartTime").is(req.getIntrusionStartTime())
                .and("batchNum").is(req.getBatchNum())
                .and("takeoffTime").is(date));
        // 调用查询方法
        List<DroneRedis> droneRedisList = (List<DroneRedis>) mongoDBClient.getByConditionAndCollectionName(query, new DroneRedis(), BaseServiceConstant.DRONE_DATA_COLLECTION);
        //droneRedis.sort(Comparator.comparing(DroneRedis::getTakeoffTime).reversed());
        if (!droneRedisList.isEmpty()) {
            DroneRedis droneRedis = droneRedisList.get(0);
            Integer type = droneRedis.getType();
            droneCoorResponse.setType(type);
            if (type == 3) { //电子身份证
                droneCoorResponse.setDriver(droneRedis.getDriver());
            }
            if (droneRedis.getPoliceDrone() != null) {
                droneCoorResponse.setPoliceDrone(droneRedis.getPoliceDrone());
            }
            if (droneRedis.getAoaDeviceId() != null) {
                droneCoorResponse.setAoaDevId(droneRedis.getAoaDeviceId());
                droneCoorResponse.setAoaDevLatitude(droneRedis.getDevLatitude());
                droneCoorResponse.setAoaDevLongitude(droneRedis.getDevLongitude());
            }
            if (droneRedis.getTargets() != null) {
                List<DroneTarget> list = new ArrayList<DroneTarget>(droneRedis.getTargets());
                List<DroneTarget> collect = list.
                        stream().filter(s -> s.getPassbyForbitArea() == 1).collect(Collectors.toList());
                if (!collect.isEmpty()) {
                    TreeSet<DroneTarget> YayunSet = new TreeSet<>(Comparator.comparing(DroneTarget::getTargetId));
                    YayunSet.addAll(collect);
                    droneCoorResponse.setNotFlyList(YayunSet);
                }
            }
            //飞手经纬度为GPS
            droneCoorResponse.setDriverLatitude(droneRedis.getGpsDriverLatitude());
            droneCoorResponse.setDriverLongitude(droneRedis.getGpsDriverLongitude());
            droneCoorResponse.setDroneCoors(droneRedis.getCoors());
        }
        return droneCoorResponse;
    }


    private List<DroneRedisWzMqttVo> getDroneRedis(List<String> strings) {
        List<DroneRedisWzMqttVo> outList = new ArrayList<>();
        for (String droneKey : strings) {
            String sys = (String) redisTemplate.opsForValue().get(droneKey);
            DroneRedis droneRedis = JSONObject.parseObject(GZipCompressUtil.uncompress(sys), DroneRedis.class);
            if (Objects.nonNull(droneRedis)) {
//                RegeoCode curRegeoCode = droneRedis.getCurRegeoCode();
//                if (Objects.isNull(curRegeoCode)) continue;
                DroneRedisWzMqttVo droneRedisHzMqttVo = BuildWzDroneRedisMqtt(droneRedis, droneKey);
                outList.add(droneRedisHzMqttVo);

            }
        }
        return outList;
    }

    private DroneRedisWzMqttVo BuildWzDroneRedisMqtt(DroneRedis droneRedis, String droneKey) {
        DroneRedisWzMqttVo droneRedisWzMqtt = new DroneRedisWzMqttVo();
        droneRedisWzMqtt.setType(droneRedis.getType());
        droneRedisWzMqtt.setBatchNum(droneRedis.getBatchNum());
        droneRedisWzMqtt.setIntrusionStartTime(droneRedis.getIntrusionStartTime());
        droneRedisWzMqtt.setDroneCode(droneRedis.getDroneUK().replaceAll("-", ""));
        droneRedisWzMqtt.setModel(droneRedis.getModel());
        droneRedisWzMqtt.setTakeoffTime(droneRedis.getTakeoffTime());
        droneRedisWzMqtt.setDiscoveryPlace(droneRedis.getDiscoveryPlace());
        droneRedisWzMqtt.setDroneKey(droneKey);
        droneRedisWzMqtt.setPoliceDrone(droneRedis.getPoliceDrone());
        droneRedisWzMqtt.setCurLatitude(droneRedis.getCurLatitude());
        droneRedisWzMqtt.setCurLongitude(droneRedis.getCurLongitude());
        droneRedisWzMqtt.setDriverLatitude(droneRedis.getDriverLatitude());
        droneRedisWzMqtt.setDriverLongitude(droneRedis.getDriverLongitude());
        droneRedisWzMqtt.setDroneSeriaID(droneRedis.getDroneSeriaID() != null ? droneRedis.getDroneSeriaID() : null);
        droneRedisWzMqtt.setPassbyForbitArea(droneRedis.getPassbyForbitArea());
        if (droneRedis.getReportId() != null) {
            droneRedisWzMqtt.setReportId(droneRedis.getReportId().longValue());
        }
        if (Objects.nonNull(droneRedis.getCurrentTargets())) {
            droneRedisWzMqtt.setCurrentTargets(droneRedis.getCurrentTargets());
        }
        droneRedisWzMqtt.setAoaDevId(droneRedis.getType().equals(2) ? droneRedis.getAoaDeviceId() : null);
        return droneRedisWzMqtt;
    }

}
